import 'dart:convert';
import 'dart:typed_data';

/// 编码工具类，用于处理不同编码格式的文本
class EncodingUtil {
  /// 尝试解码字节数据，按照多种编码方式尝试
  static String decodeBytes(Uint8List bytes) {
    // 记录尝试过的编码和错误信息
    Map<String, String> attemptedEncodings = {};
    String? decodedContent;
    
    // 尝试UTF-8解码（最常见的编码）
    try {
      decodedContent = utf8.decode(bytes);
      print('使用UTF-8成功解码');
      return decodedContent;
    } catch (e) {
      attemptedEncodings['UTF-8'] = e.toString();
      print('UTF-8解码失败: $e');
    }
    
    // 尝试latin1解码（西欧编码）
    try {
      decodedContent = latin1.decode(bytes);
      print('使用latin1成功解码');
      return decodedContent;
    } catch (e) {
      attemptedEncodings['latin1'] = e.toString();
      print('latin1解码失败: $e');
    }
    
    // 尝试Windows-1252编码（常见于Windows系统）
    try {
      // 使用自定义方法解码Windows-1252
      decodedContent = _decodeWindows1252(bytes);
      print('使用Windows-1252成功解码');
      return decodedContent;
    } catch (e) {
      attemptedEncodings['Windows-1252'] = e.toString();
      print('Windows-1252解码失败: $e');
    }
    
    // 尝试使用GBK/GB2312编码（中文常用编码）
    try {
      // 模拟GBK/GB2312解码
      // 注意：这是一个简化实现，完整支持需要使用第三方库如gbk_codec
      decodedContent = decodeGBK(bytes);
      print('使用GBK/GB2312(简化版)成功解码');
      return decodedContent;
    } catch (e) {
      attemptedEncodings['GBK/GB2312'] = e.toString();
      print('GBK/GB2312解码失败: $e');
    }
    
    // 最后使用fromCharCodes作为后备方案
    print('所有编码方式都失败，使用String.fromCharCodes作为后备方案');
    print('尝试过的编码: ${attemptedEncodings.keys.join(", ")}');
    
    // 打印文件头部字节用于调试
    if (bytes.length > 20) {
      print('文件头部20个字节: ${bytes.sublist(0, 20).map((b) => '0x${b.toRadixString(16).padLeft(2, "0")}').join(" ")}');
    }
    
    return String.fromCharCodes(bytes);
  }
  
  // 简单的Windows-1252解码实现
  static String _decodeWindows1252(Uint8List bytes) {
    return String.fromCharCodes(bytes.map((byte) {
      // 处理Windows-1252特殊字符
      if (byte >= 0x80 && byte <= 0x9F) {
        // 这些是Windows-1252中与Latin1不同的字符
        switch (byte) {
          case 0x80: return 0x20AC; // Euro sign
          case 0x82: return 0x201A; // Single low-9 quotation mark
          case 0x83: return 0x0192; // Latin small letter f with hook
          case 0x84: return 0x201E; // Double low-9 quotation mark
          case 0x85: return 0x2026; // Horizontal ellipsis
          case 0x86: return 0x2020; // Dagger
          case 0x87: return 0x2021; // Double dagger
          case 0x88: return 0x02C6; // Modifier letter circumflex accent
          case 0x89: return 0x2030; // Per mille sign
          case 0x8A: return 0x0160; // Latin capital letter S with caron
          case 0x8B: return 0x2039; // Single left-pointing angle quotation mark
          case 0x8C: return 0x0152; // Latin capital ligature OE
          case 0x8E: return 0x017D; // Latin capital letter Z with caron
          case 0x91: return 0x2018; // Left single quotation mark
          case 0x92: return 0x2019; // Right single quotation mark
          case 0x93: return 0x201C; // Left double quotation mark
          case 0x94: return 0x201D; // Right double quotation mark
          case 0x95: return 0x2022; // Bullet
          case 0x96: return 0x2013; // En dash
          case 0x97: return 0x2014; // Em dash
          case 0x98: return 0x02DC; // Small tilde
          case 0x99: return 0x2122; // Trade mark sign
          case 0x9A: return 0x0161; // Latin small letter s with caron
          case 0x9B: return 0x203A; // Single right-pointing angle quotation mark
          case 0x9C: return 0x0153; // Latin small ligature oe
          case 0x9E: return 0x017E; // Latin small letter z with caron
          case 0x9F: return 0x0178; // Latin capital letter Y with diaeresis
          default: return byte;
        }
      }
      return byte;
    }));
  }
  
  // 改进的GBK/GB2312解码实现
  // 注意：这是一个更准确的实现，使用常见的GBK编码映射
  // 完整支持需要使用第三方库如gbk_codec
  static String decodeGBK(Uint8List bytes) {
    // 首先尝试使用UTF-8解码，如果成功则直接返回
    try {
      String utf8Result = utf8.decode(bytes);
      // 检查是否包含有效的中文字符
      bool hasValidChineseChars = utf8Result.codeUnits.any((c) => c >= 0x4E00 && c <= 0x9FFF);
      if (hasValidChineseChars) {
        print('文件使用UTF-8编码，包含有效中文字符');
        return utf8Result;
      }
    } catch (e) {
      // UTF-8解码失败，继续尝试其他编码
      print('UTF-8解码失败: $e');
    }
    
    // 使用latin1解码作为基础，然后检测并修复中文字符
    String latinResult = latin1.decode(bytes);
    
    // 检查是否包含可能的GBK编码中文字符
    bool containsChineseChars = false;
    for (int i = 0; i < latinResult.length; i++) {
      int charCode = latinResult.codeUnitAt(i);
      // 检查是否在常见的乱码范围内
      if ((charCode >= 0xA1 && charCode <= 0xF7) || 
          (charCode >= 0x80 && charCode <= 0x9F)) {
        containsChineseChars = true;
        break;
      }
    }
    
    if (!containsChineseChars) {
      // 如果没有检测到可能的中文字符，直接返回latin1结果
      print('未检测到中文字符，使用latin1编码');
      return latinResult;
    }
    
    print('检测到可能的GBK编码中文字符，尝试GBK解码');
    
    // 如果检测到可能的中文字符，尝试更复杂的解码
    List<int> codeUnits = [];
    int i = 0;
    
    // 创建一个简单的GBK到Unicode映射表
    // 这只包含一些常见的映射，完整的映射表需要更多的数据
    Map<int, int> gbkToUnicode = {
      // 常见汉字区域
      0xB0A1: 0x554A, // 啊
      0xB0A3: 0x963F, // 阿
      0xB0B0: 0x5B89, // 安
      0xB0B4: 0x6309, // 按
      0xB0B9: 0x5DF4, // 巴
      0xB0BB: 0x628A, // 把
      0xB0C5: 0x767D, // 白
      0xB0C9: 0x767E, // 百
      0xB0D1: 0x8D25, // 败
      0xB0D9: 0x7248, // 版
      0xB0E0: 0x529E, // 办
      0xB0E3: 0x5E2E, // 帮
      0xB0E5: 0x699C, // 榜
      0xB0E8: 0x5305, // 包
      0xB0EC: 0x5B9D, // 宝
      0xB0F3: 0x62A5, // 报
      0xB0F6: 0x66B4, // 暴
      0xB0F8: 0x676F, // 杯
      0xB0FB: 0x5317, // 北
      0xB1A8: 0x88AB, // 被
      0xB1AD: 0x672C, // 本
      0xB1B1: 0x6BD4, // 比
      0xB1B9: 0x5FC5, // 必
      0xB1BE: 0x95ED, // 闭
      0xB1C0: 0x6BD5, // 毕
      0xB1C3: 0x5E01, // 币
      0xB1C6: 0x6C34, // 水
      0xB1CF: 0x53D8, // 变
      0xB1D9: 0x8868, // 表
      0xB1DE: 0x522B, // 别
      0xB1E4: 0x5E76, // 并
      0xB1E9: 0x75C5, // 病
      0xB1F9: 0x51B0, // 冰
      0xB2A4: 0x6CE2, // 波
      0xB2A8: 0x535A, // 博
      0xB2B7: 0x4E0D, // 不
      0xB2BB: 0x6CA1, // 没
      0xB2C9: 0x91C7, // 采
      0xB2D9: 0x8D22, // 财
      0xB2DE: 0x6750, // 材
      0xB2E3: 0x5F69, // 彩
      0xB2E5: 0x83DC, // 菜
      0xB2E9: 0x53C2, // 参
      0xB2F0: 0x9A8C, // 验
      0xB3A1: 0x4ED5, // 仕
      0xB3A3: 0x6C5F, // 江
      0xB3A4: 0x6C11, // 民
      0xB3A5: 0x4E2D, // 中
      0xB3A6: 0x56FD, // 国
      0xB3A7: 0x5317, // 北
      0xB3A8: 0x4EAC, // 京
      0xB3A9: 0x4E0A, // 上
      0xB3AA: 0x6D77, // 海
      0xB3AB: 0x5E7F, // 广
      0xB3AC: 0x5DDE, // 州
      0xB3AD: 0x5929, // 天
      0xB3AE: 0x6D25, // 津
      0xB3AF: 0x91CD, // 重
      0xB3B0: 0x5E86, // 庆
      0xB3B1: 0x6DF1, // 深
      0xB3B2: 0x5733, // 圳
      0xB3B3: 0x6210, // 成
      0xB3B4: 0x90FD, // 都
      0xB3B5: 0x676D, // 杭
      0xB3B6: 0x5DDE, // 州
      0xB3B7: 0x5357, // 南
      0xB3B8: 0x4EAC, // 京
      0xB3B9: 0x6B66, // 武
      0xB3BA: 0x6C49, // 汉
      0xB3BB: 0x897F, // 西
      0xB3BC: 0x5B89, // 安
      0xB3BD: 0x957F, // 长
      0xB3BE: 0x6C99, // 沙
      0xB3BF: 0x54C8, // 哈
      0xB3C0: 0x5C14, // 尔
      0xB3C1: 0x6EE8, // 滨
      0xB3C2: 0x90D1, // 郑
      0xB3C3: 0x5DDE, // 州
      0xB3C4: 0x6D4E, // 济
      0xB3C5: 0x5357, // 南
      0xB3C6: 0x592A, // 太
      0xB3C7: 0x539F, // 原
      0xB3C8: 0x5408, // 合
      0xB3C9: 0x80A5, // 肥
      0xB3CA: 0x798F, // 福
      0xB3CB: 0x5DDE, // 州
      0xB3CC: 0x53A6, // 厦
      0xB3CD: 0x95E8, // 门
      0xB3CE: 0x5357, // 南
      0xB3CF: 0x660C, // 昌
      0xB3D0: 0x957F, // 长
      0xB3D1: 0x6625, // 春
      0xB3D2: 0x6C88, // 沈
      0xB3D3: 0x9633, // 阳
      0xB3D4: 0x5357, // 南
      0xB3D5: 0x5B81, // 宁
      0xB3D6: 0x547C, // 呼
      0xB3D7: 0x548C, // 和
      0xB3D8: 0x6D69, // 浩
      0xB3D9: 0x7279, // 特
      0xB3DA: 0x94F6, // 银
      0xB3DB: 0x5DDD, // 川
      0xB3DC: 0x8D35, // 贵
      0xB3DD: 0x9633, // 阳
      0xB3DE: 0x6606, // 昆
      0xB3DF: 0x660E, // 明
      0xB3E0: 0x62C9, // 拉
      0xB3E1: 0x8428, // 萨
      0xB3E2: 0x897F, // 西
      0xB3E3: 0x5B81, // 宁
      0xB3E4: 0x4E4C, // 乌
      0xB3E5: 0x9C81, // 鲁
      0xB3E6: 0x6728, // 木
      0xB3E7: 0x9F50, // 齐
      0xB3E8: 0x5170, // 兰
      0xB3E9: 0x5DDE, // 州
      0xB3EA: 0x897F, // 西
      0xB3EB: 0x5B81, // 宁
      0xB3EC: 0x94F6, // 银
      0xB3ED: 0x5DDD, // 川
    };
    
    while (i < bytes.length) {
      int byte = bytes[i];
      
      // 检查是否是GBK双字节字符的开始
      if (byte >= 0x81 && byte <= 0xFE && i + 1 < bytes.length) {
        int secondByte = bytes[i + 1];
        
        // GBK的第二个字节范围通常是0x40-0xFE
        if (secondByte >= 0x40 && secondByte <= 0xFE) {
          // 计算GBK编码值
          int gbkCode = (byte << 8) | secondByte;
          
          // 打印GBK编码值用于调试
          print('检测到可能的GBK字符: 0x${gbkCode.toRadixString(16)}');
          
          // 尝试从映射表中查找Unicode值
          int? unicode = gbkToUnicode[gbkCode];
          
          if (unicode != null) {
            // 如果在映射表中找到，使用映射的Unicode值
            codeUnits.add(unicode);
          } else {
            // 如果不在映射表中，使用算法计算
            // GB2312编码范围（GBK的子集）
            if (byte >= 0xA1 && byte <= 0xF7 && 
                secondByte >= 0xA1 && secondByte <= 0xFE) {
              // GB2312编码的汉字
              int section = byte - 0xA0;
              int position = secondByte - 0xA0;
              unicode = 0x4E00 + ((section - 1) * 94 + (position - 1));
              codeUnits.add(unicode);
            }
            // GBK扩展区域
            else if ((byte >= 0x81 && byte <= 0xA0) || 
                    (byte >= 0xA1 && byte <= 0xFE && secondByte >= 0x40 && secondByte <= 0xA0)) {
              // 这里使用一个近似映射
              if (secondByte >= 0x40 && secondByte <= 0x7E) {
                unicode = 0x4E00 + ((byte - 0x81) * 190 + (secondByte - 0x40));
                codeUnits.add(unicode);
              } else if (secondByte >= 0x80 && secondByte <= 0xFE) {
                unicode = 0x4E00 + ((byte - 0x81) * 190 + (secondByte - 0x41));
                codeUnits.add(unicode);
              } else {
                // 未知映射，使用替代字符
                codeUnits.add(0xFFFD); // Unicode替代字符
              }
            } else {
              // 未知的GBK编码，使用替代字符
              codeUnits.add(0xFFFD); // Unicode替代字符
            }
          }
          
          i += 2;
          continue;
        }
      }
      
      // 对于非GBK字符，直接添加
      codeUnits.add(byte);
      i++;
    }
    
    return String.fromCharCodes(codeUnits);
  }

  /// 检查并去除UTF-8 BOM标记
  /// 
  /// 如果字符串以BOM标记开头，则去除该标记
  /// 返回处理后的字符串
  static String removeBom(String content) {
    if (content.startsWith('\uFEFF')) {
      return content.substring(1);
    }
    return content;
  }

  /// 检查并去除字节数组中的UTF-8 BOM标记
  /// 
  /// 如果字节数组以BOM标记开头，则去除该标记
  /// 返回处理后的字节数组
  static Uint8List removeBomFromBytes(Uint8List bytes) {
    if (bytes.length >= 3 && 
        bytes[0] == 0xEF && 
        bytes[1] == 0xBB && 
        bytes[2] == 0xBF) {
      return bytes.sublist(3);
    }
    return bytes;
  }
}